class Emitter {
    constructor() {
        this._observer = {};
        this._all = [];
    }

    on(type, fn) {
        if (!this._observer[type]) {
            this._observer[type] = [];
        }
        if (!this._observer[type].includes(fn)) {
            this._observer[type].push(fn);
        }
        return this;
    }

    off(type, fn) {
        let index = (this._observer[type] || []).findIndex(a => a == fn);
        if (index != -1) {
            this._observer[type].splice(index, 1);
        }
        return this;
    }

    all(fn) {
        if (!this._all.includes(fn)) {
            this._all.push(fn);
        }
    }

    emit(type, data) {
        this._all.forEach(fn => fn({ type, data }));
        (this._observer[type] || []).forEach(a => a(data));
        return this;
    }
}

export default Emitter;